package com.icesoft.core.common.helper.lock.impl;

import com.icesoft.core.common.helper.lock.base.ICacheLock;
import com.icesoft.core.common.helper.lock.base.ICacheLockGroup;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Slf4j
public class MemoryCacheLockGroupImpl implements ICacheLockGroup {
	private static ConcurrentHashMap<String, MemoryCacheLock> cacheGroupMap = new ConcurrentHashMap<>();

	@Override
	public ICacheLock getGroup(String groupName) {
		MemoryCacheLock memoryCacheLock = cacheGroupMap.putIfAbsent(groupName, new MemoryCacheLock());
		if (memoryCacheLock == null) {
			log.trace("create group:{}", groupName);
			memoryCacheLock = cacheGroupMap.get(groupName);
		}
		return memoryCacheLock;
	}

	private static class MemoryCacheLock implements ICacheLock {
		private ConcurrentHashMap<String, CountDownLatch> concurrentHashMap = new ConcurrentHashMap<>();

		@Override
		public boolean runIfLocked(String key, Runnable runnable, boolean isWait, int waitSeconds) {
			CountDownLatch signal = concurrentHashMap.putIfAbsent(key, new CountDownLatch(1));
			log.trace("cache size:{}", concurrentHashMap.size());
			if (signal == null) {
				log.trace("获取到执行锁：lock={}", key);
				try {
					runnable.run();
				} finally {
					signal = concurrentHashMap.remove(key);
					signal.countDown();
					log.trace("执行完成，释放锁");
				}
				return true;
			}
			if (isWait) {
				log.trace("等待其他线程执行：lock={}", key);
				try {
					boolean isAwait = signal.await(waitSeconds, TimeUnit.SECONDS);// 3秒中还没有执行完就停止等待
					if (!isAwait) {
						log.trace("等待其他线程执行超过3s，不再等待");
					}
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
				}
			}
			return false;
		}

	}

}
